/*
 * Utility.cpp
 *
 *  Created on: 2011. 3. 15.
 *      Author: JeeHoon
 */
#include "Utility.h"
#include "cJSON.h"
#include <string.h>
#include <stdlib.h>

int
URLEncode(char * buf,unsigned int buf_size ,char * sour)
{
#define LEFTHEX(x)		(unsigned char)x/16>=10?\
						(unsigned char)x/16-10+'A':\
                                        (unsigned char)x/16+'0';
#define RIGHTHEX(x)		(unsigned char)x%16>=10?\
						(unsigned char)x%16-10+'A':\
						(unsigned char)x%16+'0';

        int i,j;
        int len;
        unsigned int index;

        char arr[2][17][4] ={
                {"`","\\","~","$","%","^","+","|","{","}","[","]","\"","<",">",","," "} ,
                {"%60","%5C","%7E","%24","%25","%5E","%2B","%7C","%7B","%7D","%5B","%5D","%22","%3C","%3E","%2C","%20"}
        };

        index = 0;
        len = strlen(sour);

        for(i = 0 ; i < len ; i++)
        {
                if( index >= buf_size - 4 )
                {
                        return -1;
                }

                if(((unsigned)(sour[i])<=0177) == true)
                {
                        for(j = 0 ; j < 17 ; j++)
                        {
                                if(arr[0][j][0] == sour[i] )
                                {
                                        buf[index++] = arr[1][j][0];
                                        buf[index++] = arr[1][j][1];
                                        buf[index++] = arr[1][j][2];
                                        break;
                                }
                        }
                        if(j == 17)
                                buf[index++] = sour[i];
                }
                else
                {
                        buf[index++] = '%';
                        buf[index++] = LEFTHEX(sour[i]);
                        buf[index++] = RIGHTHEX(sour[i]);
                }
        }
        buf[index] = '\0';
        return 1;
}

int
URLDecode(char * buf,unsigned int buf_size ,char * sour)
{
        int i;
        int len;
        unsigned int index;

        index = 0;
        len = strlen(sour);

        for(i = 0 ; i < len ; i++)
        {
                if( sour[i] == '%')
                {
                        char ch[2];
                        unsigned char byte = 0;
                        ch[0] = sour[++i];
                        ch[1] = sour[++i];

                        if(ch[0] >= 'A' && ch[0] <= 'F')
                                byte += (ch[0] - 'A' + 10);
                        else if(ch[0] >= 'a' && ch[0] <= 'f')
								byte += (ch[0] - 'a' + 10);
                        else if(ch[0] >= '0' && ch[0] <= '9')
								byte += (ch[0] - '0');
                        else
                                return -1;

                        byte <<= 4;

                        if(ch[1] >= 'A' && ch[1] <= 'F')
                                byte += (ch[1] - 'A' + 10);
                        else if(ch[1] >= 'a' && ch[1] <= 'f')
								byte += (ch[1] - 'a' + 10);
                        else if(ch[1] >= '0' && ch[1] <= '9')
                                byte += (ch[1] - '0');
                        else
                                return -1;

                        buf[index++] = byte;
                }
                else
                {
                        buf[index++] = sour[i];
                }
        }
        buf[index] = '\0';
        return 1;
}

Osp::Base::String
getJSONObjectItem(Osp::Base::String jsonstring, Osp::Base::String name)
{
	result r = E_SUCCESS;

	cJSON * pJsonRoot = NULL;

	Osp::Base::String value(L"");
	Osp::Base::ByteBuffer * pJsonBuffer = NULL;
	Osp::Base::ByteBuffer * pNameBuffer = NULL;

	jsonstring = URLDecode(jsonstring);

	if(jsonstring == L"" || name == L"")
	{
		r = E_INVALID_ARG;
	}
	else
	{
		pJsonBuffer = Osp::Base::Utility::StringUtil::StringToUtf8N(jsonstring);
		pNameBuffer = Osp::Base::Utility::StringUtil::StringToUtf8N(name);
	}

	if(E_SUCCESS == r)
	{
		pJsonRoot = cJSON_Parse((const char*)pJsonBuffer->GetPointer());
		if(NULL == pJsonRoot)
		{
			r = E_INVALID_ARG;
		}
	}

	if(E_SUCCESS == r)
	{
		cJSON * item = cJSON_GetObjectItem(pJsonRoot,(const char*)pNameBuffer->GetPointer());
		if(NULL == item)
		{
			r = E_INVALID_ARG;
		}
		else
		{
			char * out = cJSON_Print(item);
			value.Append(out);
		}
	}

	if(NULL != pJsonRoot)
	{
		cJSON_Delete(pJsonRoot);
	}

	if(NULL != pJsonBuffer)
	{
		delete pJsonBuffer;
	}

	if(NULL != pNameBuffer)
	{
		delete pNameBuffer;
	}

	return value;
}

Osp::Base::String
_URLCoder(Osp::Base::String source , bool isEncodeing)
{
	char * buffer = NULL;
	int buff_size = 0;
	Osp::Base::String output;

	int (*func)(char * ,unsigned int  ,char * ) = NULL;

	if(isEncodeing)
	{
		func = URLEncode;
	}
	else
	{
		func = URLDecode;
	}


	if(source != L"")
	{
		buff_size = source.GetLength()+1;
		buffer = (char*)malloc(buff_size);
		if(NULL == buffer)
		{
			printLog(L"malloc fail" );
			return output;
		}
		else
		{
			buffer[0] = '\0';
		}

		Osp::Base::ByteBuffer * utf8 = Osp::Base::Utility::StringUtil::StringToUtf8N(source);
		if(utf8 != NULL)
		{

			if(-1 == func(buffer,buff_size,(char*)utf8->GetPointer()))
			{
				printLog(L"Fail URLDecode");
			}
			else
			{
				output = Osp::Base::String(buffer);
			}
			delete utf8;
			utf8 = NULL;
		}
	}

	if(NULL != buffer)
	{
		free(buffer);
	}

	return output;
}

Osp::Base::String
URLDecode(Osp::Base::String source)
{
	return _URLCoder(source , false);
}

Osp::Base::String
URLEncode(Osp::Base::String source)
{
	return _URLCoder(source , true);
}


char *
StringToChar(Osp::Base::String string)
{
	if(string == L"")
	{
		return NULL;
	}
	Osp::Base::ByteBuffer * utf8 = Osp::Base::Utility::StringUtil::StringToUtf8N(string);
	char * str = (char*)utf8->GetPointer();
	char * out = NULL;

	int len = strlen(str);
	out = (char*)malloc(len+1);

	strcpy(out,str);

	delete utf8;

	return out;
}
